package ansible

import (
	"context"
	"time"
)

// Config 包含 Ansible 执行的配置选项
type Config struct {
	// 基础配置
	BinPath        string            // Ansible 二进制文件路径
	WorkDirectory  string            // 工作目录
	Timeout        time.Duration     // 超时时间
	Environment    map[string]string // 环境变量
	
	// 输出配置
	EnablePTY      bool              // 是否启用 PTY
	OutputFormat   OutputFormat      // 输出格式
	ForceColor     bool              // 强制彩色输出
	SuppressWarnings bool            // 抑制警告
	
	// 日志配置
	Logger         *Logger           // 日志记录器
	LogLevel       string            // 日志级别
	
	// 上下文
	Context        context.Context   // 执行上下文
}

// OutputFormat 定义输出格式类型
type OutputFormat string

const (
	OutputFormatDefault OutputFormat = "default"
	OutputFormatJSON    OutputFormat = "json"
	OutputFormatTimer   OutputFormat = "timer"
	OutputFormatYAML    OutputFormat = "yaml"
)

// DefaultConfig 返回默认配置
func DefaultConfig() *Config {
	return &Config{
		BinPath:          "ansible",
		Timeout:          10 * time.Minute,
		Environment:      make(map[string]string),
		EnablePTY:        false,
		OutputFormat:     OutputFormatDefault,
		ForceColor:       false,
		SuppressWarnings: false,
		Logger:           GetDefaultLogger(),
		LogLevel:         "info",
		Context:          context.Background(),
	}
}

// DefaultPlaybookConfig 返回 Playbook 的默认配置
func DefaultPlaybookConfig() *Config {
	config := DefaultConfig()
	config.BinPath = "ansible-playbook"
	return config
}

// Clone 创建配置的副本
func (c *Config) Clone() *Config {
	env := make(map[string]string, len(c.Environment))
	for k, v := range c.Environment {
		env[k] = v
	}
	
	return &Config{
		BinPath:          c.BinPath,
		WorkDirectory:    c.WorkDirectory,
		Timeout:          c.Timeout,
		Environment:      env,
		EnablePTY:        c.EnablePTY,
		OutputFormat:     c.OutputFormat,
		ForceColor:       c.ForceColor,
		SuppressWarnings: c.SuppressWarnings,
		Logger:           c.Logger,
		LogLevel:         c.LogLevel,
		Context:          c.Context,
	}
}

// WithBinPath 设置二进制文件路径
func (c *Config) WithBinPath(path string) *Config {
	c.BinPath = path
	return c
}

// WithWorkDirectory 设置工作目录
func (c *Config) WithWorkDirectory(dir string) *Config {
	c.WorkDirectory = dir
	return c
}

// WithTimeout 设置超时时间
func (c *Config) WithTimeout(timeout time.Duration) *Config {
	c.Timeout = timeout
	return c
}

// WithContext 设置上下文
func (c *Config) WithContext(ctx context.Context) *Config {
	c.Context = ctx
	return c
}

// WithLogger 设置日志记录器
func (c *Config) WithLogger(logger *Logger) *Config {
	c.Logger = logger
	return c
}

// WithOutputFormat 设置输出格式
func (c *Config) WithOutputFormat(format OutputFormat) *Config {
	c.OutputFormat = format
	return c
}

// WithPTY 启用或禁用 PTY
func (c *Config) WithPTY(enable bool) *Config {
	c.EnablePTY = enable
	return c
}

// WithForceColor 启用或禁用强制彩色输出
func (c *Config) WithForceColor(enable bool) *Config {
	c.ForceColor = enable
	return c
}

// WithSuppressWarnings 启用或禁用警告抑制
func (c *Config) WithSuppressWarnings(suppress bool) *Config {
	c.SuppressWarnings = suppress
	return c
}

// SetEnv 设置环境变量
func (c *Config) SetEnv(key, value string) *Config {
	if c.Environment == nil {
		c.Environment = make(map[string]string)
	}
	c.Environment[key] = value
	return c
}

// SetEnvs 批量设置环境变量
func (c *Config) SetEnvs(envs map[string]string) *Config {
	if c.Environment == nil {
		c.Environment = make(map[string]string)
	}
	for k, v := range envs {
		c.Environment[k] = v
	}
	return c
}

// GetAnsibleEnvs 获取 Ansible 相关的环境变量
func (c *Config) GetAnsibleEnvs() map[string]string {
	envs := make(map[string]string)
	
	// 复制现有环境变量
	for k, v := range c.Environment {
		envs[k] = v
	}
	
	// 根据配置设置 Ansible 环境变量
	if c.OutputFormat == OutputFormatJSON {
		envs["ANSIBLE_STDOUT_CALLBACK"] = "json"
		envs["ANSIBLE_LOAD_CALLBACK_PLUGINS"] = "True"
	} else if c.OutputFormat == OutputFormatTimer {
		envs["ANSIBLE_STDOUT_CALLBACK"] = "timer"
		envs["ANSIBLE_LOAD_CALLBACK_PLUGINS"] = "True"
	}
	
	if c.ForceColor {
		envs["ANSIBLE_FORCE_COLOR"] = "True"
	}
	
	if c.SuppressWarnings {
		envs["ANSIBLE_DEPRECATION_WARNINGS"] = "false"
		envs["ANSIBLE_ACTION_WARNINGS"] = "false"
		envs["ANSIBLE_LOCALHOST_WARNING"] = "false"
		envs["ANSIBLE_INVENTORY_UNPARSED_WARNING"] = "false"
	}
	
	return envs
}
